package com.silverhaze.diamond.client.ui.dialogs;

import com.silverhaze.commons.helpers.CommonUIHelper;
import com.silverhaze.diamond.client.settings.Settings;
import com.silverhaze.diamond.client.settings.SettingsStorage;
import com.silverhaze.diamond.client.ui.panel.ErrorPanel;

import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Ivan Babanin
 * This part of code is strictly confidential.
 * © Magnificent Software Inc.
 */
public abstract class AbstractDialog extends JDialog {
    private JPanel content;
    private ErrorPanel errorPanel;

    private List<JTextComponent> fieldList = new ArrayList<JTextComponent>();

    private DialogButtonView viewType;

    public AbstractDialog(Window owner) {
        this(owner, "", true, DialogButtonView.OK_CANCEL);
    }

    public AbstractDialog(Frame owner) {
        this(owner, "", true, DialogButtonView.OK_CANCEL);
    }

    public AbstractDialog(Window owner, boolean isModal) {
        this(owner, "", isModal, DialogButtonView.OK_CANCEL);
    }

    public AbstractDialog(Frame owner, boolean isModal) {
        this(owner, "", isModal, DialogButtonView.OK_CANCEL);
    }

    public AbstractDialog(Window owner, String title, boolean isModal) {
        this(owner, title, isModal, DialogButtonView.OK_CANCEL);
    }


    public AbstractDialog(Frame owner, String title, boolean isModal) {
        this(owner, title, isModal, DialogButtonView.OK_CANCEL);
    }

    public AbstractDialog(Window owner, String title, boolean isModal, DialogButtonView viewType) {
        super(owner, title, isModal ? ModalityType.APPLICATION_MODAL : ModalityType.MODELESS);

        init(viewType);

        alignDlg(owner);
    }

    protected JPanel initializeOkCancelPanel(DialogType dialogType) {
        JPanel panel = new JPanel(new BorderLayout());

        JButton ok = new JButton(new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                okPressed();
            }
        });
        JButton cancel = new JButton(new AbstractAction("Отмена") {
            public void actionPerformed(ActionEvent e) {
                cancelPressed();
            }
        });

        if (dialogType == DialogType.CREATE) {
            ok.setText("Создать");
        } else if (dialogType == DialogType.EDIT) {
            ok.setText("Сохранить");
        } else {
            ok.setText("Закрыть");
        }

        Box hBox = Box.createHorizontalBox();
        CommonUIHelper.addToHorizontalBox(hBox,
                ok, 1, dialogType == DialogType.VIEW ? new JLabel("") : cancel);
        panel.add(hBox, BorderLayout.LINE_END);
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        return panel;
    }

    protected void init(DialogButtonView viewType) {
        setModal(true);

        setLayout(new BorderLayout());

        initializeHotKeys();

        this.viewType = viewType;
        content = new JPanel(new BorderLayout());
        errorPanel = new ErrorPanel(this);

        add(content, BorderLayout.CENTER);
        add(errorPanel, BorderLayout.PAGE_END);

        initHotKeys();
    }

    private void initializeHotKeys() {
        final InputMap inputMap = getRootPane().getInputMap();
        final ActionMap actionMap = getRootPane().getActionMap();

        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "ESCAPE");
        actionMap.put("ESCAPE", new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                AbstractDialog.this.dispose();
            }
        });

        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_MASK), "CTRL+ENTER");
        actionMap.put("CTRL+ENTER", new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                okPressed();
            }
        });
    }

//    public void add(Component comp, Object constraints) {
//        content.add(comp, constraints);
//    }

    private void initHotKeys() {
        InputMap inputMap = getRootPane().getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
        ActionMap actionMap = getRootPane().getActionMap();

        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_MASK), "Ctrl+Enter");
        actionMap.put("Ctrl+Enter", new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                okPressed();
            }
        });

        inputMap.put(KeyStroke.getKeyStroke("ESCAPE"), "Esc");
        actionMap.put("Esc", new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                cancelPressed();
            }
        });
    }

    protected String getCaption() {
        return "";
//        return getSettings().getProgramName() + " v." + getSettings().getProgramVersion() + " - ";
    }

    protected Settings getSettings() {
        return SettingsStorage.getSettings();
    }

    protected void alignDlg(Component c) {
        setLocationRelativeTo(c);
    }

    public JPanel getContent() {
        return content;
    }

    protected abstract void okPressed();

    protected void cancelPressed() {
        dispose();
    }

    public ErrorPanel getErrorPanel() {
        return errorPanel;
    }

    public void setSize(Dimension size) {
        super.setSize(size);
        setMinimumSize(size);
        setMaximumSize(size);
        setPreferredSize(size);
    }

    protected List<JTextComponent> getFieldList() {
        return fieldList;
    }

    public void enableInput(boolean editable) {
        for (JTextComponent component : getFieldList()) {
            component.setEditable(editable);
        }
    }

    protected class EnterListener extends KeyAdapter {
        public void keyReleased(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                okPressed();
            }
        }
    }

    protected JTextField createTextField(int size) {
        JTextField field = new JTextField(size);
        fieldList.add(field);
        return field;
    }

    protected JTextField createTextField(String str, int size) {
        JTextField field = new JTextField(str, size);
        fieldList.add(field);
        return field;
    }

    protected JTextArea createTextArea(int rows, int cols) {
        JTextArea area = new JTextArea(rows, cols);
        area.setBorder(new LineBorder(Color.BLACK, 1));
        area.setFont(new Font("Tahoma", Font.PLAIN, 11));
        fieldList.add(area);
        return area;
    }

    protected JTextArea createTextArea(String str, int rows, int cols) {
        JTextArea area = new JTextArea(str, rows, cols);
        area.setBorder(new LineBorder(Color.BLACK, 1));
        area.setFont(new Font("Tahoma", Font.PLAIN, 11));
        fieldList.add(area);
        return area;
    }

    protected JTextArea createArea(int rows, int columns, boolean edit) {
        if (edit) {
            return new JTextArea(rows, columns);
        }

        return new JTextArea(rows, columns);
    }

    public enum DialogButtonView {
        NO_BUTTONS,
        OK,
        CANCEL,
        OK_CANCEL
    }
}

